!// Dmitry.Konovalov@jcu.edu.au Dmitry.A.Konovalov@gmail.com, 2013

module mtrx_mod; 
use vec_mod; 
implicit none;
!private;
logical, save :: MTRX_TRACE = .FALSE.;

contains; 


subroutine mtrx_i1_range(minr, maxr, m, nr);    
  real(DP), intent(IN) :: m(:,:); 
  integer, intent(OUT) :: minr, maxr;
  integer, intent(OUT), optional :: nr;
  minr = LBOUND(m, 1);
  maxr = UBOUND(m, 1);
  if (present(nr)) nr = SIZE(m, 1);
end SUBROUTINE

subroutine mtrx_i2_range(minc, maxc, m, nc);  
  real(DP), intent(IN) :: m(:,:); 
  integer, intent(OUT) :: minc, maxc;
  integer, intent(OUT), optional :: nc;
  minc = LBOUND(m, 2);
  maxc = UBOUND(m, 2);
  if (present(nc)) nc = SIZE(m, 2);
end SUBROUTINE


subroutine mtrx_rows_dbg(minr, maxr, m, trace);   
  character(len=1024) :: mssg;   
  real(DP), intent(IN) :: m(:, :); 
  logical, optional, intent(IN) :: trace;  
  integer :: i, minr, maxr;
  if (present(trace) .AND. (.NOT. trace)) RETURN;  
  do i = minr, maxr
    write(mssg,*) TRIM(int_to_str(i)), ","; 
    call vec_dbg(TRIM(mssg), m(i, :));
  end do
end subroutine

subroutine mtrx_dbg(info, m, trace);   
  character(len=1024) :: mssg;
  character(LEN=*), intent(IN) :: info;   
  real(DP), intent(IN) :: m(:, :); 
  logical, optional, intent(IN) :: trace;  
  integer :: i, nr, mini, maxi;
  if (present(trace) .AND. (.NOT. trace)) RETURN;
  
  call mtrx_i1_range(mini, maxi, m, nr);
  write(mssg,*) info, "(", TRIM(int_to_str(mini)), &
    & ":", TRIM(int_to_str(maxi)), ")(:)="; 
  write(*, *) TRIM(mssg);  ! eg 'mem_mtrx=(1:20)(:)'
    
  if (nr <= VEC_DBG_VIEW_N) then
    do i = mini, maxi
      write(mssg,*) TRIM(int_to_str(i)), ","; 
      call vec_dbg(TRIM(mssg), m(i, :));
    end do
  else
    nr = VEC_DBG_VIEW_N / 2;
    call mtrx_rows_dbg(mini, mini + nr - 1, m, trace);
    write(*,*) "..."  
    call mtrx_rows_dbg(maxi - nr + 1, maxi, m, trace);    
  end if
end subroutine


end module 
